#include <cassert>
#include <pantheios/pantheios.hpp>
#include <pantheios/inserters.hpp>
#include "light_server_adaptor.h"
#include <ltobjectcreate.h>
#include <iltcommon.h>

#include "ltservershell.h"
#include "main_game_shell.h"
#include "shader_light.h"
#include "light_system.h"

BEGIN_CLASS(light_server_adaptor)
ADD_COLORPROP_FLAG(Color, 1.0f, 1.0f, 1.0f, NULL)
ADD_VECTORPROP_FLAG(Dir, NULL)
ADD_VECTORPROP_FLAG(Xishu, NULL)
ADD_BOOLPROP(DirLight, false)
END_CLASS_DEFAULT_FLAGS(light_server_adaptor, BaseClass, NULL, NULL, CF_ALWAYSLOAD)


light_server_adaptor::light_server_adaptor() : BaseClass(),
    m_has_added_to_system(false) {
}

uint32 light_server_adaptor::OnPrecreate(ObjectCreateStruct* pStruct, float fData) {
    BaseClass::OnPrecreate(pStruct, fData);
    pStruct->m_ObjectType = OT_NORMAL ;
    if(fData == PRECREATE_WORLDFILE) {
        read_props(pStruct) ;
    }

    return 1 ;
}

void light_server_adaptor::read_props(ObjectCreateStruct* pStruct) {
    g_pLTServer->GetPropColor("Color", &m_color) ;
    g_pLTServer->GetPropVector("Dir", &m_direction) ;
    g_pLTServer->GetPropVector("Xishu", &m_attenuation) ;
    g_pLTServer->GetPropBool("DirLight", &m_is_dir_light) ;
    if(m_attenuation.x <= 0.1f) m_attenuation.x = 1.0f ;
    m_color /= 255.0f ;
}

uint32 light_server_adaptor::OnObjectCreated(float type) {
    g_pLTServer->SetNextUpdate(m_hObject, 0.1f) ;
    try_to_added_to_light_system() ; 
    return 1 ;
}

void light_server_adaptor::try_to_added_to_light_system() {
    assert(g_pSShell) ;
    game_logic_shell* logic_shell = g_pSShell->game_logic_shell() ;
    if(!logic_shell) {
        pantheios::log_ERROR("server part logic_shell should be exist!!!, now not found!!") ;
        return  ;
    }
    m_has_added_to_system = true ;
    shader_light light ;
    light.Color[0] = m_color.x ;
    light.Color[1] = m_color.y ;
    light.Color[2] = m_color.z ;
    light.Color[3] = 1.0f ;
    LTVector pos ;
    g_pLTServer->GetObjectPos(m_hObject, &pos) ;    
    if(!m_is_dir_light) {
        light.Position[0] = pos.x;
        light.Position[1] = pos.y ;
        light.Position[2] = pos.z ;
        light.Position[3] = 1.0f ;
        light.ConstanceAttenuation = m_attenuation.x ;
        light.LinearAttenuation = m_attenuation.y ;
        light.QuadraticAttenuation = m_attenuation.z ;
    } else {
        light.Position[0] = pos.x;
        light.Position[1] = pos.y ;
        light.Position[2] = pos.z ;
        if(m_direction.x == 0.0f && m_direction.y == 0.0f && m_direction.z == 0.0f)
            m_direction.y = 1.0f ;
        light.Position[3] = 0.0f ;

    }
    
    logic_shell->lightsystem()->add_light(light) ;
    
}

uint32 light_server_adaptor::OnUpdate() {
    if(m_has_added_to_system) return 1 ; // the duty has finished.
    try_to_added_to_light_system() ;
    g_pLTServer->SetNextUpdate(m_hObject, 0.1f) ;
    return 1 ;
}
